/**
 * Author: ling
 * Create Time: 2018-11-28 15:17
 * Description: js 闭包
 */

/**
 * 单例模式
 * @param fn
 * @returns {function(): *}
 */
const getSingle = function(fn) {
  let ret;
  return function () {
    return ret || (ret = fn.apply(this, arguments))
  }
};

// 模拟AOP
/**
 * 前置
 * @param beforeFn
 * @returns {function(): *}
 */
Function.prototype.before = function (beforeFn) {
  let __this = this;
  return function () {
    beforeFn.apply(this, arguments);
    return __this.apply(this, arguments)
  }
};
/**
 * 后置
 * @param afterFn
 * @returns {function(): *}
 */
Function.prototype.after = function (afterFn) {
  let __this = this;
  return function () {
    let ret = __this.apply(this, arguments);
    afterFn.apply(this, arguments);
    return ret
  }
};

const currying = function (fn) {
  let args = [];

  return function () {
    if(arguments.length === 0) {
      return fn.apply(this, args)
    } else {
      [].push.apply(args, arguments);
      return arguments.callee
    }
  }
};

const cost = (function () {
  let money = 0;
  return function () {
    for (let arg of arguments) {
      money += arg
    }
    return money
  }
})();

// 节流
const throttle = function (fn, interval) {
  let __this = fn,
    timer,
    firstTime = true;

  return function () {
    let arg = arguments,
      __me = this;

    if(firstTime) {
      __this.apply(__me, arg);
      firstTime = false
    }

    if(timer) {
      return false
    }

    timer = setTimeout(function () {
      clearTimeout(timer);
      timer = null;
      __this.apply(__me, arg);
    }, interval || 500)
  }
};
